package com.huahai.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huahai.common.BaseResponse;
import com.huahai.common.ErrorCode;
import com.huahai.common.ResultUtils;
import com.huahai.exception.BusinessException;
import com.huahai.pojo.dto.TeamDTO;
import com.huahai.pojo.dto.TeamJoinDTO;
import com.huahai.pojo.dto.TeamQueryDTO;
import com.huahai.pojo.dto.TeamUpdateDTO;
import com.huahai.pojo.entity.Team;
import com.huahai.pojo.entity.User;
import com.huahai.pojo.entity.UserTeam;
import com.huahai.pojo.vo.TeamUserVO;
import com.huahai.pojo.vo.UserVO;
import com.huahai.service.TeamService;
import com.huahai.service.UserService;
import com.huahai.service.UserTeamService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/team")
@CrossOrigin(origins = {"http://localhost:5173/"})
@Slf4j
public class TeamController {

    @Resource
    private TeamService teamService;

    @Resource
    private UserService userService;

    @Resource
    private UserTeamService userTeamService;

    /**
     * 新增队伍
     *
     * @param teamDTO
     * @return
     */
    @PostMapping("/save")
    public BaseResponse<Long> saveTeam(@RequestBody TeamDTO teamDTO, HttpServletRequest request) {
        if (teamDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 设置请求参数
        Team team = new Team();
        BeanUtils.copyProperties(teamDTO, team);
        team.setCreateTime(LocalDateTime.now());
        team.setUpdateTime(LocalDateTime.now());
        // 获取当前登录用户
        User currentUser = userService.getCurrentUser(request);
        // 存储队伍信息
        Long result = teamService.saveTeam(team, currentUser);
        return ResultUtils.success(team.getId());
    }

    /**
     * 修改队伍信息
     *
     * @param teamUpdateDTO
     * @return
     */
    @PutMapping("/update")
    public BaseResponse<Boolean> updateTeam(@RequestBody TeamUpdateDTO teamUpdateDTO, HttpServletRequest request) {
        if (teamUpdateDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 获取当前登录用户
        User loginUser = userService.getCurrentUser(request);
        boolean result = teamService.updateTeam(teamUpdateDTO, loginUser);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
        return ResultUtils.success(true);
    }

    /**
     * 根据条件批量查询队伍
     *
     * @param teamQueryDTO
     * @return
     */
    @GetMapping("/list")
    public BaseResponse<List<TeamUserVO>> listTeams(TeamQueryDTO teamQueryDTO, HttpServletRequest request, User loginUser) {
        if (teamQueryDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 判断是否为管理员
        boolean isAdmin = userService.isAdmin(request);
        // 1. 创建查询条件
        List<TeamUserVO> teamList = teamService.listTeams(teamQueryDTO, isAdmin, loginUser);
        if (teamList.isEmpty()) {
            return ResultUtils.success(Collections.emptyList());
        }
        // 2. 检查当前登录用户是否加入了该队伍
        checkCurrentUserHasJoinTeam(request, teamList);
        // 3. 获取当前队伍已加入的人数和用户列表
        getHasJoinTeamNumberAndUsers(teamList);

        return ResultUtils.success(teamList);
    }

    /**
     * 获取当前队伍已加入的人数和用户列表
     * @param teamList
     */
    private void getHasJoinTeamNumberAndUsers(List<TeamUserVO> teamList) {
        // 3. 获取当前队伍已加入的人数和用户列表
        // 3.1 获取查询到的队伍id列表
        List<Long> teamIdList = teamList.stream().map(TeamUserVO::getId).collect(Collectors.toList());
        // 3.2 根据id列表查询用户信息
        QueryWrapper<UserTeam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.in("teamId", teamIdList);
        List<UserTeam> userTeamList = userTeamService.list(userTeamQueryWrapper);
        // 3.3 对同一teamId的用户进行分组
        Map<Long, List<UserTeam>> listMap = userTeamList.stream().collect(Collectors.groupingBy(UserTeam::getTeamId));
        teamList.forEach(team -> {
            // 3.4 获取当前已加入的人数
            List<UserTeam> sortedUserTeam = listMap.get(team.getId());
            team.setHasJoinNum((long) sortedUserTeam.size());
            // 3.5 获取当前队伍的成员列表
            List<Long> sameTeamIdList = sortedUserTeam.stream().map(UserTeam::getUserId).collect(Collectors.toList());
            // 3.5.1 根据id列表查询用户信息
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.in("id", sameTeamIdList);
            List<User> userList = userService.list(userQueryWrapper);
            List<UserVO> sameTeamUserList = new ArrayList<>();
            userList.forEach(user -> {
                // 3.5.2 将用户信息封装成UserVO
                UserVO userVO = new UserVO();
                BeanUtils.copyProperties(user, userVO);
                sameTeamUserList.add(userVO);
                // 3.5.2 封装队长信息
                if(user.getId().equals(team.getUserId())){
                    team.setUser(userVO);
                }
            });
            team.setTeamUserList(sameTeamUserList);
        });
    }

    /**
     * 检查当前登录用户是否加入了该队伍
     * @param request
     * @param teamList
     */
    private void checkCurrentUserHasJoinTeam(HttpServletRequest request, List<TeamUserVO> teamList) {
        // 判断当前登录用户是否加入了该队伍
        // 1. 获取查询到的队伍id列表
        List<Long> teamIdList = teamList.stream().map(TeamUserVO::getId).collect(Collectors.toList());
        QueryWrapper<UserTeam> userTeamQueryWrapper = new QueryWrapper<>();
        // 2.获取当前登录用户
        try {
            User currentUser = userService.getCurrentUser(request);
            // 3. 查询当前用户加入的队伍
            userTeamQueryWrapper.eq("userId", currentUser.getId());
            userTeamQueryWrapper.in("teamId", teamIdList);
            List<UserTeam> userTeamList = userTeamService.list(userTeamQueryWrapper);
            List<Long> hasJoinTeamIdList = userTeamList.stream().map(UserTeam::getTeamId).collect(Collectors.toList());
            // 4. 比较并修改hasJoin的值并返回
            for (TeamUserVO team : teamList) {
                boolean hasJoin = hasJoinTeamIdList.contains(team.getId());
                team.setHasJoin(hasJoin);
            }
        } catch (Exception ignored) {}
    }

    /**
     * 分页查询队伍信息
     *
     * @param teamQueryDTO
     * @return
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<Team>> listTeamsByPage(TeamQueryDTO teamQueryDTO) {
        if (teamQueryDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 创建查询条件
        Team team = new Team();
        BeanUtils.copyProperties(teamQueryDTO, team);
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>(team);
        // 创建分页条件
        Long pageIndex = teamQueryDTO.getPageIndex();
        Long pageSize = teamQueryDTO.getPageSize();
        Page<Team> page = new Page<>(pageIndex, pageSize);
        Page<Team> pageList = teamService.page(page, queryWrapper);
        // 返回结果
        return ResultUtils.success(pageList);
    }

    /**
     * 根据id查询用户信息
     *
     * @param id
     * @return
     */
    @GetMapping("/list/{id}")
    public BaseResponse<TeamUserVO> getTeamById(@PathVariable(value = "id") Long id, HttpServletRequest httpServletRequest) {
        if (id == null || id < 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Team team = teamService.getById(id);
        if (team == null) {
            throw new BusinessException(ErrorCode.NULL_ERROR, "队伍不存在");
        }
//        TeamQueryVO teamQueryVO = new TeamQueryVO();
//        // 获取当前队长
//        Long userId = team.getUserId();
//        User user = userService.getById(userId);
//        UserVO userVO = new UserVO();
//        BeanUtils.copyProperties(user, userVO);
//        // 封装队伍信息返回
//        BeanUtils.copyProperties(team, teamQueryVO);
//        teamQueryVO.setUser(userVO);
        List<TeamUserVO> teamList = new ArrayList<>();
        TeamUserVO teamUserVO = new TeamUserVO();
        BeanUtils.copyProperties(team, teamUserVO);
        teamList.add(teamUserVO);
        // 获取当前用户是否加入该队伍
        checkCurrentUserHasJoinTeam(httpServletRequest, teamList);
        // 获取当前队伍已加入的人数和用户列表
        getHasJoinTeamNumberAndUsers(teamList);
        return ResultUtils.success(teamList.get(0));
    }

    /**
     * 加入队伍
     *
     * @param teamJoinDTO
     * @param request
     * @return
     */
    @PostMapping("/join")
    public BaseResponse<Boolean> joinTeam(@RequestBody TeamJoinDTO teamJoinDTO, HttpServletRequest request) {
        if (teamJoinDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 获取当前登录用户
        User loginUser = userService.getCurrentUser(request);
        boolean result = teamService.joinTeam(teamJoinDTO, loginUser);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
        return ResultUtils.success(true);
    }

    /**
     * 用户退出队伍
     *
     * @param id
     * @param request
     * @return
     */
    @DeleteMapping("/quit/{id}")
    public BaseResponse<Boolean> quitTeam(@PathVariable(value = "id") Long id, HttpServletRequest request) {
        if (id == null || id < 0) {
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        // 获取当前登录用户
        User loginUser = userService.getCurrentUser(request);
        boolean result = teamService.quitTeam(id, loginUser);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
        return ResultUtils.success(true);
    }

    /**
     * 根据id删除队伍
     *
     * @param id
     * @return
     */
    @DeleteMapping("/delete/{id}")
    public BaseResponse<Boolean> deleteTeam(@PathVariable(value = "id") Long id, HttpServletRequest request) {
        if (id == null || id < 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 获取当前登录用户
        User loginUser = userService.getCurrentUser(request);
        boolean result = teamService.removeTeam(id, loginUser);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
        return ResultUtils.success(true);
    }

    /**
     * 查询当前登录用户创建的队伍
     *
     * @param teamQueryDTO
     * @return
     */
    @GetMapping("/list/current/create")
    public BaseResponse<List<TeamUserVO>> listCreateTeamsCurrentUser(TeamQueryDTO teamQueryDTO, HttpServletRequest request) {
        if (teamQueryDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 获取当前登录用户
        User loginUser = userService.getCurrentUser(request);
        // 判断是否为管理员
        boolean isAdmin = userService.isAdmin(request);
        // 创建查询条件
        teamQueryDTO.setUserId(loginUser.getId());
        List<TeamUserVO> teamList = teamService.listTeams(teamQueryDTO, isAdmin, loginUser);
        if (teamList.isEmpty()) {
            return ResultUtils.success(Collections.emptyList());
        }
        checkCurrentUserHasJoinTeam(request, teamList);
        return ResultUtils.success(teamList);
    }

    /**
     * 查询当前用户加入的队伍
     *
     * @param teamQueryDTO
     * @return
     */
    @GetMapping("/list/current/join")
    public BaseResponse<List<TeamUserVO>> listJoinTeamsCurrentUser(TeamQueryDTO teamQueryDTO, HttpServletRequest request) {
        if (teamQueryDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 获取当前登录用户
        User loginUser = userService.getCurrentUser(request);
        // 创建查询条件
        QueryWrapper<UserTeam> userTeamQueryWrapper = new QueryWrapper<>();
        userTeamQueryWrapper.eq("userId", loginUser.getId());
        List<UserTeam> userTeamList = userTeamService.list(userTeamQueryWrapper);
        // 获取userTeamList中的teamId列表
        // userId teamId (groupingBy)作用展示
        // 1      1
        // 2      1
        // 2      2
        // teamId userId
        // 1 -> 1,2
        // 2 -> 2
        Map<Long, List<UserTeam>> listMap = userTeamList.stream().collect(Collectors.groupingBy(UserTeam::getTeamId));
        List<Long> idList = new ArrayList<>(listMap.keySet());
        teamQueryDTO.setIdList(idList);
        List<TeamUserVO> teamList = teamService.listTeams(teamQueryDTO, true, loginUser);
        if (teamList.isEmpty()) {
            return ResultUtils.success(Collections.emptyList());
        }
        checkCurrentUserHasJoinTeam(request, teamList);
        return ResultUtils.success(teamList);
    }


}
